package de.oszimt.matse.messenger;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Map;

import de.oszimt.matse.messenger.dao.DAOInterface;
import de.oszimt.matse.messenger.exceptions.UserAlreadyInContactListException;
import de.oszimt.matse.messenger.exceptions.UserDoesNotExistException;
import de.oszimt.matse.messenger.messages.ActivationMessage;
import de.oszimt.matse.messenger.messages.ContactListMessage;
import de.oszimt.matse.messenger.messages.Message;
import de.oszimt.matse.messenger.messages.TextMessage;

public class MessengerService 
{
	private DAOInterface userDAO;

	public void initializeUser(User user, String userName) throws UserDoesNotExistException
	{
		user.init(this.userDAO.getUserData(userName));
	}
	
	public void dispatchActivationFlags(User user, boolean isActive) throws UserDoesNotExistException
	{
		for (Map.Entry<String, User> curRegistration : user.getRegisteredUser().entrySet())
		{
			ArrayList<String> contactList = this.userDAO.getContactList(curRegistration.getValue().getName());
			if (contactList.contains(user.getName()))
			{
				curRegistration.getValue().getMessageQueue().add(new ActivationMessage(user.getName(), isActive));
			}
		}
	}
	
	public void extendContact(User user, String userName2) throws UserDoesNotExistException, UserAlreadyInContactListException
	{
		this.userDAO.addContact(user.getName(), userName2);
		user.getMessageQueue().add(new ContactListMessage(this.userDAO.getContactList(user.getName())));
		User user2 = user.getRegisteredUser().get(userName2);
		if (user2 != null)
		{
			user2.getMessageQueue().add(new ContactListMessage(this.userDAO.getContactList(user2.getName())));
			user2.getMessageQueue().add(new ActivationMessage(user.getName(), true));
			user.getMessageQueue().add(new ActivationMessage(userName2, true));
		}
	}
	
	public void reduceContact(User user, String userToRemove) throws UserDoesNotExistException
	{
		this.userDAO.removeContact(user.getName(), userToRemove);
		user.getMessageQueue().add(new ContactListMessage(this.userDAO.getContactList(user.getName())));
		User newUser = user.getRegisteredUser().get(userToRemove);
		if (newUser != null)
		{
			newUser.getMessageQueue().add(new ContactListMessage(this.userDAO.getContactList(newUser.getName())));
			newUser.getMessageQueue().add(new ActivationMessage(user.getName(), false));
			user.getMessageQueue().add(new ActivationMessage(userToRemove, false));
		}
	}
	
	public void setInitialMessages(User user) throws UserDoesNotExistException
	{
		ArrayList<String> contactList = this.userDAO.getContactList(user.getName());
		user.getMessageQueue().add(new ContactListMessage(contactList));
		for (String contact : contactList)
		{
			for (Map<String, Object> message : this.userDAO.getMessages(user.getName(), contact))
			{
				String textMessage = message.get(User.MESSAGE).toString();
				String sender = message.get(User.SENDER).toString();
				String receiver = message.get(User.RECIPIENT).toString();
				user.getMessageQueue().add(new TextMessage(sender, receiver, textMessage));
			}
			if (user.getRegisteredUser().containsKey(contact))
			{
				user.getMessageQueue().add(new ActivationMessage(contact, true));
			}
		}
	}
	
	public void processTextMessage(User sender, String receiverName, String message) throws UserDoesNotExistException
	{
		this.userDAO.storeMessage(sender.getName(), receiverName, message);
		sender.getMessageQueue().add(new TextMessage(sender.getName(), receiverName, message));
    	User receiver = sender.getRegisteredUser().get(receiverName);
    	if (receiver != null)
    	{
    		receiver.getMessageQueue().add(new TextMessage(sender.getName(), receiverName, message));
    	}
	}
	
	public String getJSONMessages(User user)
	{
		LinkedList<Message> queue = user.getMessageQueue();
		String jsonMsg = "{'items':[ ";
		while(!queue.isEmpty())
		{
			jsonMsg = jsonMsg + queue.pollFirst().getJSONString() + ",";
		}
		jsonMsg = jsonMsg.substring(0, jsonMsg.length() - 1) + "]}";
		return jsonMsg;
	}

	public void logout(User user) throws UserDoesNotExistException
	{
		this.userDAO.deleteMessages(user.getName());
		this.dispatchActivationFlags(user, false);
		user.destroy();
	}
	
	public DAOInterface getUserDAO() {
		return this.userDAO;
	}

	public void setUserDAO(DAOInterface userDAO) {
		this.userDAO = userDAO;
	}
}
